package cn.ztydata.teachingsystem.heaven.web.controller;

import cn.ztydata.teachingsystem.exception.ServiceException;
import cn.ztydata.teachingsystem.exception.UploadException;
import cn.ztydata.teachingsystem.heaven.common.WebContext;
import cn.ztydata.teachingsystem.heaven.cons.Constants;
import cn.ztydata.teachingsystem.heaven.cons.MsgTemplate;
import cn.ztydata.teachingsystem.heaven.entity.Student;
import cn.ztydata.teachingsystem.heaven.entity.Teacher;
import cn.ztydata.teachingsystem.heaven.entity.User;
import cn.ztydata.teachingsystem.heaven.service.StudentService;
import cn.ztydata.teachingsystem.heaven.service.TeacherService;
import cn.ztydata.teachingsystem.heaven.util.UploadUtil;
import cn.ztydata.teachingsystem.heaven.web.dto.PersonalInfoDto;
import cn.ztydata.teachingsystem.heaven.web.dto.StudentDto;
import cn.ztydata.teachingsystem.heaven.web.dto.TeacherDto;
import cn.ztydata.teachingsystem.heaven.web.dto.UserPasswordDto;
import cn.ztydata.teachingsystem.heaven.web.wrapper.HttpSessionProxy;
import cn.ztydata.teachingsystem.webservice.result.json.JsonResult;
import cn.ztydata.teachingsystem.webservice.result.json.JsonResultData;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

/**
 * 个人信息控制器类
 *
 * @author fanruiping
 * @since 2014-11-28
 */
@Controller
@RequestMapping("/personalInfo")
public class PersonalInfoController extends BaseController {
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private WebContext webContext;
    @Value("${session.key}")
    private String sessionKey;

    /**
     * 更新个人信息
     * @param dto
     * @return JsonResult
     *
     * @author fanruiping
     * @since 2014-11-28
     */
    @RequestMapping(value = "/teacherSaveEdit", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult teacherSaveEdit(@Valid @RequestBody TeacherDto dto){
        Teacher entity = mapper.map(dto, Teacher.class);

        try{
            teacherService.update(entity);

            log.debug("teacherInfo update success:return true");

            return new JsonResult(true, "个人信息更新成功");

        }catch(ServiceException ex){
            log.debug("teacherInfo update success:return false");

            return new JsonResult(false, "个人信息更新失败");
        }
    }

    /**
     * 上传图像
     * @return JsonResult
     *
     * @author fanruiping
     * @since 2014-12-17
     */
    @RequestMapping(value = "/photo", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult photo(@RequestParam("imageData") MultipartFile coverFile){
        //定义允许上传的图片类型
        List fileTypes = Lists.newArrayList("jpg", "png", "gif");
        String url = null;

        try {
            //校验上传的文件
            UploadUtil.validateFile(coverFile, fileTypes);

            //保存上传的图片
            String saveDir = Constants.UPLOAD_DIR + "/" + "userFace/";
            String fileExt = UploadUtil.getFileExt(coverFile.getOriginalFilename());
            url = saveDir + UploadUtil.generateFileName(fileExt);

            File file = new File(webContext.getRootDirPath(), url);
            FileUtils.writeByteArrayToFile(file, coverFile.getBytes());
        } catch (IOException ex) {
            log.debug("上传用户头像异常:IOException");

            log.warn("上传用户头像失败:url->" + url, ex);
            return new JsonResultData<>(false, "上传失败");
        } catch (UploadException | ServiceException ex) {
            log.debug("上传用户头像异常:UploadException|ServiceException");

            return new JsonResultData<>(false, ex.getMessage().isEmpty() ? "上传失败" : ex.getMessage());
        }

        Map<String, String> result = Maps.newHashMap();
        result.put("photoUrl", url);

        log.debug("返回上传头像url");

        return new JsonResultData<>(result);
    }

    /**
     * 修改密码
     * @param passwordDto 密码dto
     * @return JsonResult
     *
     * @author fanruiping
     * @since 2014-12-29
     */
    @RequestMapping(value = "/teacherEditPassword", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult teacherEditPassword(@RequestBody UserPasswordDto passwordDto,HttpServletRequest request){
        User userInfo = (User)((HttpSessionProxy)request.getSession()).getAttribute(sessionKey);

        if(!teacherService.checkUserPassword(passwordDto.getOldPassword(),userInfo.getUserId())){
            log.debug("oldPassword is wrong:!teacherService.checkUserPassword(oldPassword,userInfo.getUserId())");

            return new JsonResult(false,"原密码错误");
        }

        if(teacherService.changePassword(passwordDto.getNewPassword(),userInfo.getUserId())){
            log.debug("密码更改成功:teacherService.changePassword(newPassword,userInfo.getUserId())");

            return new JsonResult(true,"密码修改成功");
        }

        log.debug("密码更改失败:!teacherService.changePassword(newPassword,userInfo.getUserId())");

        return new JsonResult(false,"密码修改失败");
    }

    /**
     * 更改学生信息
     * @param studentDto 学生
     * @return JsonResult
     *
     * @author wyh
     * @since 2015-03-23
     */
    @RequestMapping(value = "/studentSaveEdit", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult updateStudent(@RequestBody @Valid StudentDto studentDto){
        studentService.updateStudent(mapper.map(studentDto, Student.class));

        log.debug("返回 更改学生信息成功");
        return new JsonResult(true, "更改成功");
    }

    /**
     * 修改密码
     * @param passwordDto 密码dto
     * @return JsonResult
     *
     * @author wyh
     * @since 2015-03-23
     */
    @RequestMapping(value = "/studentEditPassword", method = RequestMethod.POST)
    @ResponseBody
    public JsonResult updateStudentPwd(@RequestBody UserPasswordDto passwordDto){
        if(!studentService.checkPwd(passwordDto.getOldPassword())){
            log.debug("原密码错误：!studentService.checkPwd(oldPassword)");
            return new JsonResult(false, "原密码错误");
        }

        studentService.changePwd(webContext.getUserId(), passwordDto.getNewPassword());

        log.debug("返回 修改学生密码成功");
        return new JsonResult(true, "修改成功");
    }

    /**
     * 获得个人明细
     * @param role 0教师 1学生
     * @param id id
     * @return Json
     *
     * @author wyh
     * @since 2015-03-31
     */
    @RequestMapping(value = "/info/{role}/{id}", method = RequestMethod.GET)
    @ResponseBody
    public JsonResultData<PersonalInfoDto> getInfo(@PathVariable int role, @PathVariable long id){
        Assert.isTrue(role == 0 || role == 1, MessageFormat.format(MsgTemplate.ARG_VALIDATION_ERR, "角色ID"));
        Assert.isTrue(id > 0, MessageFormat.format(MsgTemplate.ARG_VALIDATION_ERR, "ID"));

        log.debug("返回 个人明细");
        return new JsonResultData<>(mapper.map(role == 0 ? teacherService.getInfo(id) : studentService.getDetail(id), PersonalInfoDto.class));
    }
}
